import { useModel } from "@umijs/max"
import { useRef } from "react"

export default function websocketModel() {
  const wsIsOpenRef = useRef(false)
  const websocketRef = useRef(null)
  const pyCallbacksRef = useRef<Record<number, Function>>({})
  const callNumberRef = useRef<number>(0)
  const { updateEapData } = useModel("eapModel")
  const { showModal } = useModel("modalModel")
  const createWebSocket = () => {
    if (!wsIsOpenRef.current || websocketRef.current === null) {
      // 创建websocket连接,如果websocket没有打开或者websocket===null的时候
      const page = window.location.pathname.substring(1)
      const websocketAddr = `ws://localhost:9099/eel?page=${page}`
      const ws = new WebSocket(websocketAddr)

      // websokcet 打开事件
      ws.onopen = () => {
        console.log("WebSocket onopen")
        wsIsOpenRef.current = true
        websocketRef.current = ws
      }

      // websocket 关闭事件
      ws.onclose = () => {
        console.log("WebSocket onclose")
        wsIsOpenRef.current = false
        websocketRef.current = null
      }

      // websocket 监听消息事件
      ws.onmessage = (e) => {
        const message = JSON.parse(e.data)
        dealPythonMessage(message)
      }
    }
  }

  const objToJson = (obj: any) => {
    return JSON.stringify(obj, (k, v) => (v == undefined ? null : v))
  }

  const callPy = async (
    objName: string,
    funcName: string,
    args: any[]
  ): Promise<ResponseData> => {
    callNumberRef.current = callNumberRef.current + 1
    console.log(`in callPy: ${objName},${funcName}`, args)
    const callId = callNumberRef.current
    const callObject = {
      call: callId,
      objName: objName,
      funcName: funcName,
      args
    }
    if (websocketRef.current && wsIsOpenRef.current) {
      websocketRef.current.send(objToJson(callObject))
    }
    return new Promise(function (resolve) {
      pyCallbacksRef.current[callObject.call] = resolve
    })
  }

  const dealPythonMessage = (message: any) => {
    if (message.hasOwnProperty("return")) {
      const callId = message.return as number
      if (message.return in pyCallbacksRef.current) {
        console.log("recv message(return)", message.value)
        pyCallbacksRef.current[message.return](message.value)
        delete pyCallbacksRef.current[callId]
      }
    } else if (message.hasOwnProperty("UpdateEapModel")) {
      console.log("recv message(UpdateEapModel): ", message.UpdateEapModel)
      updateEapData(message.UpdateEapModel)
    } else if (message.hasOwnProperty("ShowModal")) {
      console.log("recv message(ShowModal): ", message.ShowModal)
      showModal(message.ShowModal)
    }
  }

  return {
    createWebSocket,
    callPy,
    wsIsOpenRef
  }
}
